/*
 * @Author: yangni 920556271@qq.com
 * @Date: 2023-12-13 10:53:25
 * @LastEditors: yangni 920556271@qq.com
 * @LastEditTime: 2024-05-17 14:19:05
 * @FilePath: /yt-devops/lib/pages/site/site_overview/component/site_ennergy_flow.dart
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import 'dart:async';

import 'package:bruno/bruno.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:yt_devops/components/gaps.dart';
import 'package:yt_devops/pages/site/site_overview/site_overview_model.dart';
import 'package:yt_devops/resources/resources.dart';
import 'package:yt_devops/resources/str_res_keys.dart';
import 'package:yt_devops/services/site/site_services.dart';
import 'package:yt_devops/styles/styles.dart';
import 'package:yt_devops/utils/enums.dart';
import 'dart:math' as math;
import 'animate_line/animate_line_view.dart';

class SiteEnergyFlowWidget extends StatefulWidget {
  /// 站点id
  final int? siteID;

  final PowerStationType? energyType;

  const SiteEnergyFlowWidget(this.siteID, {this.energyType});

  @override
  State<SiteEnergyFlowWidget> createState() => _SiteEnergyFlowState();
}

class _SiteEnergyFlowState extends State<SiteEnergyFlowWidget> {
  Timer? timer;

  Map<EnergyDeviceType, EnergyFlowModel> energyFlowMap = {};

  Map<EnergyDeviceType, Image> deviceImage = {
    EnergyDeviceType.grid: Image.asset(
      ImageAssets.sitePowerGrid,
      width: 67.w,
    ),
    EnergyDeviceType.load: Image.asset(
      ImageAssets.siteLoad,
      width: 78.w,
    ),
    EnergyDeviceType.userPower: Image.asset(
      ImageAssets.siteLoad,
      width: 78.w,
    ),
    EnergyDeviceType.storage: Image.asset(
      ImageAssets.siteStoredEnergy,
      width: 78.w,
    ),
    EnergyDeviceType.charge: Image.asset(
      ImageAssets.siteCharge,
      width: 78.w,
    ),
    EnergyDeviceType.pv: Image.asset(
      ImageAssets.sitePv,
      width: 79.w,
    ),
  };

  List<String> fourPathList = [
    "M${0.w},${0} L${78.w},${45}",
    "M${155.08.w},${0} L${78.w},${45}",
    "M${155.08.w},${90} L${78.w},${44.5}",
    "M${0.w},${89.5} L${77.0762609.w},${45}",
  ];

  List<String> threePathList = [
    "M${0.w},${67} L${78.w},${67}",
    "M${156.w},${67} L${78.w},${67}",
    "M${78.w},${145.55} L${78.w},${67}",
  ];

  List<String> get twoPathList => [fourPathList[0], fourPathList[2]];

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.only(top: 32, bottom: 8),
      alignment: Alignment.topCenter,
      child: scFlowChart(),
    );
  }

  Map<EnergyDeviceType, dynamic> getPosition(PowerStationType? type) {
    switch (type) {
      case PowerStationType.pvStorageAndCharging:
        return {
          EnergyDeviceType.grid: {
            'line': {'right': 273.w, 'top': 0.0},
            'device': {'right': 250.w, 'top': 46.0},
          },
          EnergyDeviceType.storage: {
            'line': {'right': 65.w, 'top': 0.0},
            'lineHeight': 64.0,
            'device': {'right': 56.w, 'top': 46.0},
          },
          EnergyDeviceType.userPower: {
            'line': {'left': 272.w, 'top': 136.0},
            'detail': {'right': 16.w, 'bottom': 0.0},
            'device': {'right': 56.w, 'top': 180.0},
          },
          EnergyDeviceType.pv: {
            'line': {'right': 272.w, 'top': 136.0},
            'device': {'left': 48.w, 'top': 180.0},
          },
        };
      case PowerStationType.opticalStorage:
        return {
          EnergyDeviceType.grid: {
            'line': {'right': 273.w, 'top': 0.0},
            'device': {'left': 58.w, 'top': 46.0},
          },
          EnergyDeviceType.storage: {
            'line': {'right': 65.w, 'top': 0.0},
            'lineHeight': 64.0,
            'device': {'right': 56.w, 'top': 46.0},
          },
          EnergyDeviceType.userPower: {
            'line': {'left': 272.w, 'top': 136.0},
            'device': {'right': 56.w, 'top': 180.0},
          },
          EnergyDeviceType.pv: {
            'line': {'right': 272.w, 'top': 136.0},
            'device': {'left': 48.w, 'top': 180.0},
          },
        };
      case PowerStationType.storageAndCharging:
        return {
          EnergyDeviceType.grid: {
            'line': {'right': 273.w, 'top': 0.0},
            'device': {'left': 58.w, 'top': 46.0},
          },
          EnergyDeviceType.storage: {
            'line': {'right': 65.w, 'top': 0.0},
            'lineHeight': 64.0,
            'device': {'right': 56.w, 'top': 46.0},
          },
          EnergyDeviceType.userPower: {
            'line': {'top': 141.0, 'left': 220.w},
            'detail': {'bottom': 0.0},
            'device': {'top': 180.0, 'left': 146.w},
          },
        };
      case PowerStationType.photocharging:
        return {
          EnergyDeviceType.grid: {
            'line': {'right': 273.w, 'top': 0.0},
            'device': {'left': 58.w, 'top': 46.0},
          },
          EnergyDeviceType.charge: {
            'line': {'left': 260.w, 'top': 0.0},
            'device': {'right': 58.w, 'top': 50.0},
          },
          EnergyDeviceType.load: {
            'line': {'left': 256.w, 'top': 136.0},
            'device': {'top': 180.0, 'right': 56.w},
          },
          EnergyDeviceType.pv: {
            'line': {'left': 272.w, 'top': 136.0},
            'device': {'left': 48.w, 'top': 180.0},
          },
        };
      case PowerStationType.photovoltaic:
        return {
          EnergyDeviceType.grid: {
            'line': {'right': 273.w, 'top': 0.0},
            'device': {'left': 58.w, 'top': 46.0},
          },
          EnergyDeviceType.pv: {
            'line': {'right': 65.w, 'top': 0.0},
            'lineHeight': 100.0,
            'device': {'right': 52.w, 'top': 52.0},
          },
          EnergyDeviceType.load: {
            'line': {'top': 141.0, 'left': 220.w},
            'device': {'top': 180.0, 'left': 146.w},
          }
        };
      case PowerStationType.energyStorage:
        return {
          EnergyDeviceType.grid: {
            'line': {'right': 273.w, 'top': 0.0},
            'device': {'right': 250.w, 'top': 46.0},
          },
          EnergyDeviceType.storage: {
            'line': {'right': 67.w, 'top': 0.0},
            'lineHeight': 64.0,
            'device': {'right': 56.w, 'top': 50.0},
          },
          EnergyDeviceType.load: {
            'line': {'top': 141.0, 'left': 220.w},
            'device': {'top': 180.0, 'left': 146.w},
          }
        };
      case PowerStationType.chargingStation:
        return {
          EnergyDeviceType.grid: {
            'line': {'right': 273.w, 'top': 0.0},
            'device': {'right': 250.w, 'top': 46.0},
          },
          EnergyDeviceType.charge: {
            'line': {'left': 260.w, 'top': 0.0},
            'device': {'left': 239.w, 'top': 50.0},
          },
          EnergyDeviceType.load: {
            'line': {'top': 141.0, 'left': 220.w},
            'device': {'top': 180.0, 'left': 146.w},
          }
        };
      default:
        return {
          EnergyDeviceType.grid: {
            'line': {'right': 273.w, 'top': 0.0},
            'device': {'left': 58.w, 'top': 46.0},
          },
          EnergyDeviceType.load: {
            'line': {'left': 272.w, 'top': 136.0},
            'device': {'top': 180.0, 'right': 56.w},
          },
        };
    }
  }

  @override
  void initState() {
    getData();
    super.initState();
    timer = Timer.periodic(const Duration(seconds: 10), (timer) {
      getData();
    });
  }

  @override
  void dispose() {
    timer?.cancel();
    super.dispose();
  }

  void dealtDataCallback(List data) {
    energyFlowMap = {};
    for (var item in data) {
      var type = EnergyDeviceType.getType(item['type']);
      if (type != null) {
        var model = EnergyFlowModel.fromJson(item);
        energyFlowMap[type] = model;
      }
    }

    if (mounted) {
      setState(() {});
    }
  }

  getData() async {
    var map = await SiteServices().getSiteEnergyFlow({'siteId': widget.siteID});
    num? power;
    if (map == null) {
      return;
    }
    if (map['load']?['power'] is String) {
      power = num.tryParse(map['load']?['power']);
    } else if (map['load']?['power'] is num) {
      power = map['load']?['power'];
    }
    map['list'].add({
      'type': EnergyDeviceType.userPower.value,
      'p': power,
      'direction': power == 0 || power == null
          ? FlowDirection.stops.value
          : FlowDirection.ins.value,
    });
    dealtDataCallback(map['list']);
  }

  bool isEmptyPower(EnergyFlowModel? model) =>
      model?.p == null || model?.p == 0;

  /// 光储能量流动图
  Widget scFlowChart() {
    if (energyFlowMap.isEmpty) {
      return Gaps.empty;
    }
    List<Widget> widgets = [];
    List<AnimateLineModel> lineList = [];

    var flowPositionMap = getPosition(widget.energyType);
    var keys = flowPositionMap.keys.toList();
    var paths = keys.length == 2
        ? twoPathList
        : keys.length == 3
            ? threePathList
            : fourPathList;

    for (var i = 0; i < keys.length; i++) {
      var devicePostion = flowPositionMap[keys[i]]['device'];
      var linePostion = flowPositionMap[keys[i]]['line'];
      var detailPostion = flowPositionMap[keys[i]]['detail'];

      var model = energyFlowMap[keys[i]];
      // 负载有功率时，方向永远流进
      var direction = model?.direction ?? FlowDirection.stops;

      // 能源流动的线
      lineList.add(
        AnimateLineModel(path: paths[i], direction: direction),
      );

      // 设备名称+功率
      widgets.add(
        powerDataLineWidget(keys[i], flowPositionMap, model!),
      );

      // 设备图
      widgets.add(
        Positioned(
          left: devicePostion['left'],
          right: devicePostion['right'],
          top: devicePostion['top'],
          bottom: devicePostion['bottom'],
          child: deviceImage[keys[i]]!,
        ),
      );

      if (keys[i] == EnergyDeviceType.userPower && detailPostion != null) {
        widgets.add(detailWidget(detailPostion));
      }
    }

    if (keys.length == 3) {
      widgets.insert(
        0,
        Positioned(
          top: 40,
          child: AnimateLineView(
            size: Size(156.08.w, 146.55),
            lineList: lineList,
          ),
        ),
      );
    } else {
      widgets.insert(
        0,
        Positioned(
          top: 109,
          child: AnimateLineView(
            size: Size(155.08.w, 90),
            lineList: lineList,
            duration: Duration(milliseconds: keys.length == 4 ? 3500 : 2000),
          ),
        ),
      );
    }
    return SizedBox(
      width: double.infinity,
      height: 270,
      child: Stack(
        alignment: Alignment.center,
        children: [
          ...widgets,
          Positioned(
            top: keys.length == 3 ? 99 : 144,
            child: SizedBox(
              width: 24.w,
              child: Image.asset(
                'assets/images/flow_point.png',
                fit: BoxFit.fill,
              ),
            ),
          ),
        ],
      ),
    );
  }

  Positioned powerDataLineWidget(
    EnergyDeviceType type,
    Map<EnergyDeviceType, dynamic> flowPositionMap,
    EnergyFlowModel model,
  ) {
    var position = flowPositionMap[type]['line'];

    var powerWidget = Text.rich(TextSpan(
        text: model.getValueStr,
        children: [TextSpan(text: ' ${model.unit}', style: TextStyles.lf11)],
        style: TextStyles.f16.mediumStyle.dinStyle));
    var nameWidget = Text(type.label, style: TextStyles.lf12);

    var left = position['left'] != null ? position['left'] + 7.w : null;
    var right = position['right'] != null ? position['right'] + 7.w : null;

    double lineOffsetHeight =
        (flowPositionMap[type]['lineHeight'] ?? 60.0) - 60;

    return Positioned(
      left: left,
      right: right,
      top: position['top'],
      bottom: position['bottom'],
      child: BrnDashedLine(
        color: const Color(0xFF939AA0),
        axis: Axis.vertical,
        dashedThickness: 0.5.w,
        dashedOffset: -7.w,
        dashedLength: 60 + lineOffsetHeight,
        position: position['left'] != null
            ? BrnDashedLinePosition.leading
            : BrnDashedLinePosition.trailing,
        contentWidget: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            powerWidget,
            nameWidget,
            SizedBox(
              height: 22 + lineOffsetHeight,
            )
          ],
        ),
      ),
    );
  }

  Positioned detailWidget(Map detailPostion) {
    return Positioned(
      left: detailPostion['left'],
      right: detailPostion['right'],
      top: detailPostion['top'],
      bottom: detailPostion['bottom'],
      child: Text.rich(
        TextSpan(
          text: ResKey.devicechargingPile.tr,
          children: [
            TextSpan(
                text: '${energyFlowMap[EnergyDeviceType.charge]?.getValueStr}',
                style: TextStyles.f12.mediumStyle),
            TextSpan(
                text:
                    '${energyFlowMap[EnergyDeviceType.charge]?.unit}/${ResKey.deviceOtherLoad.tr}'),
            TextSpan(
                text: '${energyFlowMap[EnergyDeviceType.load]?.getValueStr}',
                style: TextStyles.f12.mediumStyle),
            TextSpan(text: '${energyFlowMap[EnergyDeviceType.load]?.unit}'),
          ],
          style: TextStyles.styleWith(
            12.sp,
            color: Colour.labelTextColor,
          ),
        ),
      ),
    );
  }
}
